/* ************************************************************************ */
/*                                                                          */
/*  Copyright (c)2005 Russell Weir | damonsbane _at_ gmail                  */
/*                                                                          */
/* This library is free software; you can redistribute it and/or            */
/* modify it under the terms of the GNU Lesser General Public               */
/* License as published by the Free Software Foundation; either             */
/* version 3.0 of the License, or (at your option) any later version.       */
/*                                                                          */
/* This library is distributed in the hope that it will be useful,          */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of           */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        */
/* Lesser General Public License or the LICENSE file for more details.      */
/*                                                                          */
/* ************************************************************************ */

package tzparser;

import neko.io.File;
import haxe.io.Bytes;

class ZoneChangeSet {
	var changes : Array<ZoneChange>;
	var zonenames : Array<String>;
	var className : String;
	
	public function new(name:String) {
		className = name;
		changes = new Array<ZoneChange>();
		zonenames = new Array<String>();
	}

	public function add(t:ZoneChange) : Void {
		changes.push(t);
		var have : Bool = false;
		for(i in zonenames) {
			if(i == t.name) {
				have = true;
				break;
			}
		}
		if(!have) {
			zonenames.push(t.name);
		}
	}

	function sort() {
	}

	// Work around neko 1.6 MAX_STACK_PER_FUNCTION set to 128
	public function toString() : String {
		sort();
		var sb = new StringBuf();
		var sbfuncs = new StringBuf();

		sb.add("\t\tabbrev = new Array();\n");
		var idx = 0;
		var count = 0;
		var start : Bool = true;

		// not many abbreviations, should not affect neko
		while(idx < zonenames.length) {
			sb.add("\t\t");
			sb.add("abbrev.push(");
			sb.add(Parser.quotedString(zonenames[idx]));
			sb.add(");\n");
			idx++;
		}

		/*
		while(idx < zonenames.length) {
			if(start) {
				sb.add("\t\tvar abbrev_"+Std.string(count)+" : Array<String> = [\n");
				start = false;
			}
			sb.add("\t\t\t");
			sb.add(Parser.quotedString(zonenames[idx]));
			if((idx%50 == 0 && idx != 0) || idx == zonenames.length -1) {
				sb.add("\n\t\t];\n");
				sb.add("\t\tabbrev = abbrev.concat(abbrev_"+Std.string(count)+");\n");
				count++;
				start = true;
			}
			else {
				sb.add(",\n");
			}
			idx++;
		}
		*/

		var maxs : String = File.getContent("max_changes");
		var max = Std.parseInt(StringTools.trim(maxs));
		if(max == null || changes.length > max) {
			var fp = File.write("max_changes", true);
			fp.write(Bytes.ofString(Std.string(changes.length)));
			fp.close();
			fp = File.write("max_name", true);
			fp.write(Bytes.ofString(className));
			fp.close();
		}

		sb.add("\n\t\tchanges = new Array();\n");
		idx = 0;
		count = 0;
		start = true;
	
		while(idx < changes.length) {
			if(start) {
				sb.add("\t\tinits_"+Std.string(count)+"();\n");
				sbfuncs.add("\n\tstatic function inits_"+Std.string(count)  +"() {\n");
				start = false;
			}
			sbfuncs.add("\t\tchanges.push(");
			changes[idx].setZoneNames(zonenames);
			sbfuncs.add(changes[idx]);
			sbfuncs.add(");\n");
			if((idx%15 == 0 && idx != 0) || idx == changes.length -1) {
				sbfuncs.add("\t}\n");
				count++;
				start = true;
			}
			idx++;
		}
		/*
		while(idx < changes.length) {
			if(start) {
				sb.add("\t\tvar changes_"+Std.string(count)+" : Array<ChangeRecord> = [\n");
				start = false;
			}
			sb.add("\t");
			changes[idx].setZoneNames(zonenames);
			sb.add(changes[idx]);
			if((idx%10 == 0 && idx != 0) || idx == changes.length -1) {
				sb.add(changes[idx].comment());
				sb.add("\n\t\t];\n");
				sb.add("\t\tchanges = changes.concat(changes_"+Std.string(count)+");\n");
				count++;
				start = true;
			}
			else {
				sb.add(", ");
				sb.add(changes[idx].comment());
				sb.add("\n");
			}
			idx++;
		}*/
		sb.add("\t\tinitialized = true;\n\t}\n");
		sb.add(sbfuncs.toString());
		return sb.toString();
	}
}